package com.o2opuzi.lib.db;

import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;

import org.springframework.jdbc.core.JdbcTemplate;


@SuppressWarnings("unchecked")
public class ModelRepository <M extends Model<M, Integer>>{
	
	
	@Resource(name="jdbcTemplate")
	public JdbcTemplate db;
	
	
	public Map<String, Object> findOne(List<String> cols,Map<String, Object> where){
		M m = createModel().cols(cols).where();
		int i =0;
		for (Entry<String, Object> en : where.entrySet()) {
			if(i== 0){
				m.eq(en.getKey(), en.getValue());
			}else{
				m.and().eq(en.getKey(), en.getValue());
			}
			i++;
		}
		return m.select();
	}
	
	public List<Map<String, Object>> findList(List<String> cols,Map<String, Object> where,Integer page,Integer size){
		M m = createModel().cols(cols).where();
		int i =0;
		for (Entry<String, Object> en : where.entrySet()) {
			if(i== 0){
				m.eq(en.getKey(), en.getValue());
			}else{
				m.and().eq(en.getKey(), en.getValue());
			}
			i++;
		}
		if(page != null && size != null){
			return m.selectList(page, size);
		}
		return m.selectList();
	}
	
	public List<Map<String, Object>> findList(List<String> cols,Map<String, Object> where){
		return findList(cols, where,null,null);
	}
	
	
	public Map<String, Object>get(Integer id){
		return createModel().select(id);
	}
	
	
	
	/**
	 * 创建一个模型
	 * @auther Y.hj
	 * @param modelClass
	 * @return
	 */
	public static <T> T createModel(Class<T> modelClass){
		try {
			return modelClass.newInstance();
		} catch (Exception e) {
			throw new DbException(e);
		}
	}
	
	
	/**
	 * 获取当前model的class
	 * @auther Y.hj
	 * @return
	 */
	private synchronized  Class<M> getModelClass(){
		return (Class<M>) (((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
	}
	
	/**
	 * 穿件模型对象
	 * @auther Y.hj
	 * @return
	 */
	public M createModel(){
		return createModel(getModelClass());
	}
	
	
	public Map<String, Object> findBy(String where,Object...params){
		return createModel().where(where, params).select();
	}
	
	public List<Map<String, Object>> findListBy(String where,Object...params){
		return createModel().where(where, params).selectList();
	}
	
	public Page<Map<String, Object>> findPageListBy(int page,int pageSize,String where,Object...params){
		return createModel().where(where, params).selectPage(page, pageSize);
	}

	
	public M dbModel(){
		return createModel();
	}
	
	public M dbModel(String as){
		return createModel().as(as);
	}
	
	public M dbModel(String as,List<Object> list){
		List<String> cols = new ArrayList<String>(list.size());
		for (Object obj : list) {
			cols.add(obj.toString());
		}	
		return dbModel(as).cols(cols);
	}
	
	public List<M> getModelList(){
		return createModel().selectModelList();
	}
	
	public boolean fieldExists(String field,Object value){
		return createModel().hasField(field, value);
	}
	
	
	public List<Map<String, Object>> getList(){
		return createModel().selectList();
	}
	
	
	public List<Map<String, Object>> getList(Integer page,Integer size){
		return createModel().selectList(page, size);
	}
	
	
	
	
	public M getModel(Integer id){
		return createModel().selectModel(id);
	}
	
	public List<M>getModelList(Integer page,Integer size){
		return createModel().selectModelList(page, size);
	}
	
	
	public Map<String, Object> getById(Integer id){
		return createModel().select(id);
	}
	
	
	/**
	 * 更新
	 * @auther Y.hj
	 * @param model
	 * @return
	 */
	public int update(Map<String, Object> model){
		return createModel().update(model);
	}
	
	/**
	 * 执行更新
	 * @auther Y.hj
	 * @param sql 
	 * @param params
	 * @return
	 */
	public int update(String sql,Object...params){
		return createModel().db().update(sql, params);
	}
	
	
	/**
	 * 查询列表
	 * @auther Y.hj
	 * @param sql
	 * @param params
	 * @return
	 */
	public List<Map<String, Object>> executeQueryList(String sql,Object...params){
		return createModel().db().queryForList(sql, params);
	}
	
	/**
	 * 查询返回map
	 * @auther Y.hj
	 * @param sql
	 * @param params
	 * @return
	 */
	public Map<String, Object> executeQueryMap(String sql,Object...params){
		List<Map<String,Object>> list = executeQueryList(sql, params);
		if(list.size() > 0){
			return list.get(0);
		}
		return null;
	}
	
	public int update(Where where){
		return createModel().where(where.getSQLString(), where.getParams()).update();
	}
	
	public int update(M model){
		return model.update();
	}
	
	/**
	 * 删除
	 * @auther Y.hj
	 * @param id
	 * @return
	 */
	public int delete(Integer id){
		return createModel().delete(id);
	}
	
	public int delete(Where where){
		return createModel().where(where.getSQLString(), where.getParams()).delete();
	}
	
	
	public Integer save(Map<String, Object> model){
		return createModel().save(model);
	}
	
	public Integer save(M model){
		return createModel().save(model);
	}
	
	public M query(String...columns){
		return createModel().cols(columns);
	}
	
	public Map<String, Object> findById(Integer id){
		return createModel().select(id);
	}
	
}
